#include <cstdlib>
#include <cstring>
#include <cctype>
#include <strtrim.h>
#include "hex.h"
#include "jni.h"
#include "log.h"

void print_hex(const char* src,int len){
    char str[64];
    int offset = 0;
    for (int i = 0 ; i < len; i++){
        offset += sprintf(str+offset,"%02x ",src[i]);
        if( (i + 1) % 4 == 0 )
            offset += sprintf(str+offset," ");
        if( (i + 1) % 16 == 0){
            str[offset-2] = '\n';
            str[offset-1] = '\0';
            offset = 0;
            LOGD("%s\n",str);
        }
    }
    if( len % 16 != 0){
        str[offset] = '\n';
        str[offset + 1] = '\0';
        LOGD("%s\n",str);
    }
}

void print_hex(const uint8_t* src,int len){

    print_hex( (char*)src, len);

}

/* ret的长度应该>=3 * length + 2 */
//void byteArray2Hex(const uint8_t* src, int length,char *& ret){
//    ret = (char*)malloc(sizeof(sizeof(char)*(3 * length + 2)));
//     int offset = 0;
//     for (int i = 0 ; i < length; i++){
//     	offset += sprintf(ret+offset,"%02x ",src[i]);
//     }
//    ret[3 * length] = '\n';
//    ret[3 * length + 1] = '\0';
//}

/* ret的长度应该>=3 * length + 2 */
void byteArray2Hex(const uint8_t* src, int length,char ret[3 * length + 1]){
    int offset = 0;
    for (int i = 0 ; i < length; i++){
        offset += sprintf(ret+offset,"%02x ",src[i]);
    }
    ret[3 * length ] = '\0';
}

int hex2byteArray(const char* source, unsigned char* dest, int sourceLen)
{
    short i;
    unsigned char highByte, lowByte;

    for (i = 0; i < sourceLen; i += 2)
    {
        highByte = toupper(source[i]);
        lowByte  = toupper(source[i + 1]);

        if (highByte > 0x39)
            highByte -= 0x37;
        else
            highByte -= 0x30;

        if (lowByte > 0x39)
            lowByte -= 0x37;
        else
            lowByte -= 0x30;

        dest[i / 2] = (highByte << 4) | lowByte;
    }
    return sourceLen/2;
}

int hex2byteArray_trim(const char* source, int sourceLen,unsigned char* dest){
//    char source_trim[sourceLen+1];
    char source_trim[sourceLen];
    for(int i = 0; i < sourceLen; i++)
        if(!isxdigit(source[i]))
            return -1;

    int source_trim_len = StrTrim(source, sourceLen,source_trim);
    if(source_trim_len%2 != 0){
        //右补0
//        source_trim[source_trim_len] = '0';
//        source_trim_len ++;
        source_trim_len --;
    }
    return hex2byteArray(source_trim,dest,source_trim_len);
}

//int hex2byteArray_trim(const char* source, int sourceLen,unsigned char* dest, int destLen){
//    char src_trim[sourceLen];
//    char temp[2] = {'0','0'};
//    int i =0, k = 0,l = 0;
//    for(;i<sourceLen;i++) {
//        if (source[i] != ' ') {
//            temp[k] = source[i];
//            k++;
//            if (k == 2) {
//                k = 0;
//                memcpy(src_trim + l, temp, 2);
//                temp[0] = '0';
//                temp[1] = '0';
//                l += 2;
//            }
//        } else {
//            if (k == 1) {
//                temp[1] = temp[0];
//                temp[0] = '0';
//                k = 0;
//                memcpy(src_trim + l, temp , 2);
//                temp[0] = '0';
//                temp[1] = '0';
//                l += 2;
//            }
//        }
//    }
//    if (k == 1) {
//        temp[1] = temp[0];
//        temp[0] = '0';
//        memcpy(src_trim + l, temp , 2);
//        l += 2;
//    }
//    if(destLen<(l/2))
//        return -1;
//    return hex2byteArray(src_trim,dest,l);
//}


int lbc2byteArray(const char* source, unsigned char* dest, int sourceLen){
    int i;
    for(i=0;i<(sourceLen/2);i++){
        dest[i] = ((source[2*i]<<4)&0xf0) + (source[2*i+1]&0x0f);
    }
    if(sourceLen%2!=0){
        dest[i] = (source[2*i]<<4)&0xf0;
        i++;
    }
    return i;
}

extern "C"
JNIEXPORT void JNICALL
Java_cd_hex_Hex_print_1hex(JNIEnv
*env, jclass type,jbyteArray  src, int index, int length)
{
    jbyte *psrc;
    jboolean isCopy;

    psrc = env->GetByteArrayElements( src, &isCopy);

    if(psrc == NULL)
        return ;

    print_hex((char *)(psrc+index),length);

    env->ReleaseByteArrayElements(src, psrc, 0);
}

extern "C"
JNIEXPORT jstring JNICALL
Java_cd_hex_Hex_byteArray2Hex(JNIEnv *env, jclass type, jbyteArray src_, jint index, jint length) {
    char ret[3*length+1];
    jbyte *src;

    src = env->GetByteArrayElements(src_, NULL);

    byteArray2Hex( (uint8_t*) (src+index),  length,ret);

    env->ReleaseByteArrayElements(src_, src, 0);


    return env->NewStringUTF(ret);
}

extern "C"
JNIEXPORT jint JNICALL
Java_cd_hex_Hex_hex2byteArray_1trim(JNIEnv *env, jclass type, jstring source_, jint sourceLen,
                                    jbyteArray dest_) {
    int result = -1;
    const char *source = env->GetStringUTFChars(source_, 0);
    jbyte *dest = env->GetByteArrayElements(dest_, NULL);

    result = hex2byteArray_trim( (char*)source, sourceLen, (unsigned char*)dest);

    env->ReleaseStringUTFChars(source_, source);
    env->ReleaseByteArrayElements(dest_, dest, 0);
    return result;
}